package com.xianshijian.oauth.server.controller;

import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xianshijian.oauth.common.entity.OAuth;
import com.xianshijian.oauth.common.entity.OAuthResult;
import com.xianshijian.oauth.server.service.OAuthService;

/**
 * 换取access_token接口.
 * 
 * @author lzj
 *
 */
@Controller
public class AccessTokenController {

    @Autowired
    private OAuthService oAuthService;

    private static final Logger LOG = LoggerFactory.getLogger(AccessTokenController.class);

    @RequestMapping(value = "/oauth2/accessToken", method = RequestMethod.POST)
    public @ResponseBody Object accessToken(HttpServletRequest request) throws URISyntaxException {
        try {
        	//*********************************获取参数*********************************//
            String thirdPartyId = request.getParameter(OAuth.OAUTH_THIRD_PARTY_ID);
            String sign = request.getParameter(OAuth.OAUTH_SIGN); // 客户端加密后的clientSecret
            String redirectURL = request.getParameter(OAuth.OAUTH_REDIRECT_URL); // 得到到客户端重定向地址
            String code = request.getParameter(OAuth.OAUTH_CODE); // 授权码
            String scope = request.getParameter(OAuth.OAUTH_SCOPE); 
            
          //*********************************验证参数*********************************//
            if (StringUtils.isBlank(thirdPartyId)) {
            return OAuthResult.build(OAuth.StatusCode.THIRD_PARTY_ID_ERROR,
            "客户端验证失败，失败原因：错误的third_party_id");
            }
           
            if (StringUtils.isBlank(code)) {
            return OAuthResult.build(OAuth.StatusCode.CODE_ERROR,
            "客户端验证失败，失败原因：错误的code");
            }
           
            if (StringUtils.isBlank(redirectURL)) {
            return OAuthResult.build(OAuth.StatusCode.REDIRECT_URL_ERROR,
            "客户端验证失败，失败原因：错误的redirectURL");
            }
            
            if (StringUtils.isBlank(sign)) {
            return OAuthResult.build(OAuth.StatusCode.SIGN_ERROR,
            "客户端验证失败，失败原因：错误的sign");
            }
            
            if (StringUtils.isBlank(scope)) {
            return OAuthResult.build(OAuth.StatusCode.SCOPE_ERROR,
            "客户端验证失败，失败原因：错误的scope");
            }
            
            try {
                // 验证签名
                oAuthService.checkThirdPartyIdThirdPartySecret(thirdPartyId, sign, redirectURL, code, scope);
            } catch (Exception e) {
                LOG.error("客户端验证失败，失败原因：错误的client_id或者错误的sign" + ". thirdPartyId:" + thirdPartyId + "sign:" + sign
                        + "redirectURL:" + redirectURL + "code: " + code);
                return OAuthResult.build(OAuth.StatusCode.SIGN_ERROR, "客户端验证失败，失败原因：错误的sign");
            }

            // 生成access_token
            String accessToken = UUID.randomUUID().toString();

            // 保存access_token
            boolean flag = oAuthService.addAccessToken(code, accessToken);

            if (flag == true) {
                // 封装返回参数
                Map<String, Object> resultMap = new HashMap<String, Object>();
                resultMap.put("accessToken", accessToken);
                resultMap.put("expireIn", oAuthService.getExpireIn());
                return OAuthResult.ok(resultMap);
            } else {
                return OAuthResult.build(OAuth.StatusCode.SERVER_ERROR, "服务端错误");
            }

        } catch (Exception e) {
            // 打印错误日志
            String msg = "调用accessToken出错 : {" + e.getMessage() + "}";
            String errMsg = new StringBuilder(msg).append(", 请求参数为:[{}]").toString();
            LOG.error(errMsg, Arrays.asList(new Object[] { request }));
            LOG.error("错误信息:", e);
            throw new RuntimeException(msg, e);
        }
    }

}
